package com.gopay.scheduler.job;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import com.gopay.common.domain.cps.transfer.BatchTransferRefuseVO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.gopay.common.constants.batch.BatchPayStep;
import com.gopay.common.constants.batch.BatchProcessStatus;
import com.gopay.common.constants.proccode.ProcCodeConstants;
import com.gopay.common.constants.trans.TxnStaCode;
import com.gopay.common.constants.txncd.IntTxnCd;
import com.gopay.common.domain.cps.CpsBatchPayTask;
import com.gopay.common.domain.cps.transfer.BatchTransferToBank4AirVO;
import com.gopay.common.domain.cps.transfer.BatchTransferToBankVO;
import com.gopay.common.domain.cps.transfer.BatchTransferToGopayVO;
import com.gopay.common.domain.cps.vo.CPSResponse;
import com.gopay.common.order.dao.CommonQueryDAO;
import com.gopay.common.util.DateUtils;
import com.gopay.scheduler.GopayBaseJob;
import com.gopay.scheduler.common.CallCPSHelper;

/**
 * 企业审核批量付款Job
 * 
 * @CorpAuditBatchPayJob.java
 * @author fanghw
 * @2013-10-31 上午11:53:14 www.gopay.com.cn Inc.All rights reserved.
 */
public class CorpAuditBatchPayJob extends GopayBaseJob {

    private Logger logger = LoggerFactory.getLogger(CorpAuditBatchPayJob.class);
    
    
    /**
     * 定时任务每隔3分钟执行一次
     */
    private int intervalMinite;
    
    /**
     * 每秒能处理的最大子订单数量
     */
    private static final int SECOND_ORDER_NUM=20;

    /**
     * 公共查询Dao
     */
    @Resource(name = "commonQueryDAO")
    private CommonQueryDAO commonQueryDAO;

    /**
     * 访问CPS辅助类
     */
    @Resource(name = "callCPSHelper")
    private CallCPSHelper callCPSHelper;

    @Override
    public void doJobInternal() {
       

        // 查询等待执行异步账务的批量付款任务
        List<CpsBatchPayTask> taskList = queryWaitingAcpsBatchTasks(50);
        logger.error("CorpAuditBatchPayJob taskList size :"+taskList.size());

        if (taskList != null && taskList.size() > 0) {
            //计算出间隔时间里能执行完的批量任务列表,剩下的等待下次job执行
            int maxOrderNum=intervalMinite*60*SECOND_ORDER_NUM;
            int orderCount=0;
            List<CpsBatchPayTask> runTaskList=new ArrayList<CpsBatchPayTask>();
            for(int i=0;i<taskList.size();i++){
                CpsBatchPayTask task=taskList.get(i);
                orderCount+=task.getBatchCount().intValue();
                
                if(orderCount>maxOrderNum){
                    break;
                }
                
                runTaskList.add(task);
            }
                        
            Object paramVo = null;
            CPSResponse response;
            for (CpsBatchPayTask task : runTaskList) {
                paramVo = null;

                if (IntTxnCd._00700.value.equals(task.getLastUpdTrancode())) {
                    // 批量付款到银行
                    paramVo = build00700BatchParamVo(task.getBatchTaskId());
                }else if (IntTxnCd._00701.value.equals(task.getLastUpdTrancode())) {
                    // 批量付款到银行
                    paramVo = build00701BatchParamVo(task.getBatchTaskId());
                } else if (IntTxnCd._00900.value.equals(task.getLastUpdTrancode())) {
                    // 批量付款到国付宝
                    // paramVo=build00900BatchParamVo(task.getBatchTaskId());
                }else if(IntTxnCd._01203.value.equals(task.getLastUpdTrancode())){
                    //批量收款退款
                    paramVo = build01203BatchParamVo(task.getBatchTaskId());
                }
                
                if (paramVo != null) {
                    try {
                        logger.error("-------BatchTaskId="+task.getBatchTaskId());
                        // 调用cps
                        response=callCPSHelper.callByVOTicket(paramVo);
                        if (!ProcCodeConstants.PROC_CODE_100S1000.equals(response.getRespCode())) {
                            logger.error("------调用cps返回异常  response="+response.getRespCode());
                        }

                    } catch (Exception e) {
                        // 吃掉所有异常
                        logger.error("callByVOTicket Error", e);
                    }
                }
            }
            
            logger.error("complete task num="+runTaskList.size());
        }
        
        
        logger.error("redoOptimisticLockOrderOf00700------start------");
        //重新执行乐观锁订单之批量付款到银行        
        redoOptimisticLockOrderOf00700();
        logger.error("redoOptimisticLockOrderOf00700------end------");

        
    }

	/**
     * 查询等待执行异步账务的批量付款任务
     * 
     * @param pageSize
     * @return
     */
    private List<CpsBatchPayTask> queryWaitingAcpsBatchTasks(int pageSize) {
        List<CpsBatchPayTask> taskList = new ArrayList<CpsBatchPayTask>();

        StringBuilder sb = new StringBuilder();

        sb.append(" select t1.BATCH_TASK_ID, t1.last_upd_trancode, t1.batch_process_status,t1.BATCH_COUNT ");
        sb.append(" from (select t.BATCH_TASK_ID, t.last_upd_trancode, t.batch_process_status,t.BATCH_COUNT ");
        sb.append("         from CPS_BATCH_PAY_TASK t ");
        sb.append("        where t.batch_process_status = :batchStatus ");
        sb.append("        order by t.GOPAY_TXN_TM asc) t1 ");
        sb.append(" where rownum <= :pageSize ");

        Map<String, Object> map = new HashMap<String, Object>();
        map.put("batchStatus", BatchProcessStatus.WAITING_ASYNCHRONOUS_ACPS.value);
        map.put("pageSize", pageSize);

        List<Object[]> rsList = commonQueryDAO.findBySql(sb.toString(), map);
        CpsBatchPayTask r = null;
        if (rsList != null && rsList.size() > 0) {
            for (Object[] arr : rsList) {
                r = new CpsBatchPayTask();
                r.setBatchTaskId(((BigDecimal) arr[0]).longValue());
                r.setLastUpdTrancode((String) arr[1]);
                r.setBatchProcessStatus((String) arr[2]);
                r.setBatchCount((BigDecimal) arr[3]);
                
                taskList.add(r);
            }
        }

        return taskList;
    }

    /**
     * 构造批量付款到银行请求参数VO
     * 
     * @param cpsTaskId
     * @return
     */
    private Object build00700BatchParamVo(long cpsTaskId) {
        BatchTransferToBankVO paramVo = new BatchTransferToBankVO();
        paramVo.setCurBizStep(BatchPayStep.JOB_ASYNCHRONOUS_ACPS);
        paramVo.setCpsTaskId(String.valueOf(cpsTaskId));

        return paramVo;
    }

	/**
	 * 构造批量退款转账请求参数VO
	 * @param batchTaskId
	 * @return
	 */
    private Object build00701BatchParamVo(long batchTaskId) {
        BatchTransferToBank4AirVO paramVo = new BatchTransferToBank4AirVO();
        paramVo.setCurBizStep(BatchPayStep.JOB_ASYNCHRONOUS_ACPS);
        paramVo.setCpsTaskId(String.valueOf(batchTaskId));

        return paramVo;
    }

    /**
     * 构造批量收款转账请求参数VO
     * @param batchTaskId
     * @return
     */
    private Object build01203BatchParamVo(long batchTaskId) {
        BatchTransferRefuseVO paramVo = new BatchTransferRefuseVO();
        paramVo.setCurBizStep(BatchPayStep.JOB_ASYNCHRONOUS_ACPS);
        paramVo.setCpsTaskId(String.valueOf(batchTaskId));

        return paramVo;
    }

    /**
     * 构造批量付款到国付宝请求参数VO
     * 
     * @param cpsTaskId
     * @return
     */
    private Object build00900BatchParamVo(long cpsTaskId) {
        BatchTransferToGopayVO paramVo = new BatchTransferToGopayVO();
        paramVo.setStep(BatchPayStep.JOB_ASYNCHRONOUS_ACPS.value);
        paramVo.setBatchTaskId(String.valueOf(cpsTaskId));

        return paramVo;
    }

    public int getIntervalMinite() {
        return intervalMinite;
    }

    public void setIntervalMinite(int intervalMinite) {
        this.intervalMinite = intervalMinite;
    }
    
    /**
     * 重新执行乐观锁订单之批量付款到银行
     */
    private void redoOptimisticLockOrderOf00700(){
        StringBuilder sb = new StringBuilder();
        
        sb.append(" select m.gopay_order_id,t.batch_task_id from cps_gen_main_order m ");
        sb.append(" left join cps_batch_task_target_rel r on r.batch_target_id=m.gopay_order_id ");
        sb.append(" left join cps_batch_pay_task t on t.batch_task_id=r.batch_task_id ");
        sb.append(" where 1=1 ");
        sb.append("  and t.batch_process_status='"+BatchProcessStatus.SUCCESS.value+"' ");
        sb.append("  and m.accounting_point is null ");
        sb.append(" and m.txn_sta_cd="+TxnStaCode.TXN_STA_CD_30003.value);
        sb.append("  and m.gopay_int_txn_cd='00700' ");
        sb.append("  and m.gopay_txn_tm>= to_timestamp(:preMonth, 'yyyymmdd') ");
       
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(new Date());
        calendar.add(Calendar.DAY_OF_MONTH, -30);
        //日期T-30
        String preMonth=DateUtils.format(calendar.getTime(), "yyyyMMdd");
        
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("preMonth", preMonth);

        List<Object[]> rsList = commonQueryDAO.findBySql(sb.toString(), map);
        String gopayOrderId,cpsTaskId;
        BatchTransferToBankVO paramVo;
        CPSResponse response;
        if (rsList != null && rsList.size() > 0) {
            logger.error("OptimisticLockOrder--rsList.size="+rsList.size());
            
            for (Object[] arr : rsList) {
                gopayOrderId=(String) arr[0];
                cpsTaskId=((BigDecimal) arr[1]).toString();
                
                paramVo = new BatchTransferToBankVO();
                paramVo.setCurBizStep(BatchPayStep.JOB_OPTIMISTIC_LOCK_ORDER);
                paramVo.setCpsTaskId(cpsTaskId);
                paramVo.setGopayOrderId(gopayOrderId);
                
                
                try {
                    logger.error("callCps-------gopayOrderId="+gopayOrderId+",cpsTaskId="+cpsTaskId);
                    // 调用cps
                    response=callCPSHelper.callByVOTicket(paramVo);
                    if (!ProcCodeConstants.PROC_CODE_100S1000.equals(response.getRespCode())) {
                        logger.error("------调用cps返回异常  response="+response.getRespCode());
                    }

                } catch (Exception e) {
                    // 吃掉所有异常
                    logger.error("callByVOTicket Error", e);
                }
            }
        }
    }

}
